package uil;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.Scrollbar;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerAdapter;
import java.awt.event.ContainerEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URL;
import java.nio.CharBuffer;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import javax.swing.BoxLayout;
import javax.swing.JApplet;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import pdm.Pdm;
import pdm.StoreItem;

import net.sourceforge.chart2d.Chart2DProperties;
import net.sourceforge.chart2d.Dataset;
import net.sourceforge.chart2d.GraphChart2DProperties;
import net.sourceforge.chart2d.GraphProperties;
import net.sourceforge.chart2d.LBChart2D;
import net.sourceforge.chart2d.LegendProperties;
import net.sourceforge.chart2d.MultiColorsProperties;
import net.sourceforge.chart2d.Object2DProperties;

public class Display implements AdjustmentListener, ActionListener {

	private static final long serialVersionUID = -3848029226192759050L;
	private static double[] URMvariables;
	private static double[] DEAvariables;
	private static LBChart2D lbchart;
	private static Scrollbar sb;
	private static Label distance;
	private static Label varPdm;
	private static Label varDea;
	private static Label varUrm;
	private JFrame frame = null;
	private JFrame frameFileSelection = null;
	JFileChooser chooser = new JFileChooser();
	private java.awt.List list;
	private Button t;
	public static List<StoreItem> transitionlist;

	
	public Display() {
		super();
		initFileSelection();
		
	}
	private void initFileSelection(){
		frameFileSelection = new JFrame("Input Selection");
		frameFileSelection.addWindowListener (
			      new WindowAdapter() {
			        public void windowClosing (WindowEvent e) {
			          destroy();
			    } } );
		Label l = new Label("Please select file input. Input data must match the following pattern: ");
		Label pattern = new Label("Pattern:' Input1;Input2;...InputN&;Output1;Output2;Output3;...OutputN '");
		Label warning = new Label("REMARKS: First row is header row. Double values supported. Comma separator is '.'");
		Button but = new Button("Select input file");
		but.setActionCommand("FILE");
		but.addActionListener(this);
		JPanel x = new JPanel();
		x.setLayout(new BoxLayout(x, BoxLayout.Y_AXIS));
		x.add(l);
		x.add(pattern);
		x.add(warning);
		x.add(but);
		frameFileSelection.setContentPane(x);
		frameFileSelection.pack();
		frameFileSelection.setVisible(true);
		
		
	}
	private void selectFile(){
		String filename = getSelectedFile();
		if(filename != null){
			try{
				Pdm.setInputFileName(filename);
			}
			catch(Exception e){
				JOptionPane.showMessageDialog(null, "Wrong input format", "Error", JOptionPane.OK_OPTION);
				e.printStackTrace();
				return;
			}
			initDisplay();
			this.initMenuDisplay();
			frameFileSelection.dispose();
		}
		else{
			
		}
	}
	private String getSelectedFile(){
		int returnVal = chooser.showOpenDialog(frameFileSelection);
	    if(returnVal == JFileChooser.APPROVE_OPTION) {
	       System.out.println("You chose to open this file: " +
	            chooser.getSelectedFile().getAbsolutePath());
	       return chooser.getSelectedFile().getAbsolutePath();
	    }
	    return null;
	}
	private void setURMandDEALines() {

		Display.DEAvariables = Pdm.getDEAWeights();
		Display.URMvariables = Pdm.getURMWeights();
	}
	
	private void SelectDMU(int dmu){
		Pdm.Initialize(dmu);
		this.setURMandDEALines();
		this.displayChartFrame();
	}
	private void initDisplay(){
		frame = new JFrame("PDM Example");
		frame.setSize(new Dimension(850,550));
		frame.addWindowListener (
			      new WindowAdapter() {
			        public void windowClosing (WindowEvent e) {
			          destroy();
			    } } );
		frame.setLayout(new BorderLayout());
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	    frame.setLocation (
	      (screenSize.width - frame.getSize().width) / 2,
	      (screenSize.height - frame.getSize().height) / 2);
	    frame.setVisible(true);
	}
	private void initMenuDisplay(){
		
		JPanel appPanel = new JPanel();
		appPanel.setLayout(new BoxLayout(appPanel, BoxLayout.Y_AXIS));
		
		list = new java.awt.List(10);
		//list.se
		for(int i = 1;i <=Pdm.dea.dmulist.size();i++){
			list.add(String.valueOf(i), i-1);
		}
		appPanel.add(list);
		
		t = new Button("Show selected DMU ");
		t.setActionCommand("NEWDMU");
		t.addActionListener(this);
		
		appPanel.add(t);
		
		frame.getContentPane().add(appPanel, BorderLayout.WEST);
		frame.repaint();
	}
	/**
	 * Close both Windows and quit app process
	 */
	public void destroy() {

		    if (frame != null) frame.dispose();
		    if (frameFileSelection != null) frameFileSelection.dispose();
	}
	private void displayChartFrame() {
				
		JPanel p = new JPanel();
		
		sb = new Scrollbar(Scrollbar.VERTICAL, 0, 1, 1, Display.transitionlist.size()+1);
		sb.addAdjustmentListener(this);
		distance = new Label();
		varPdm = new Label("PDM Values: ");
		varDea = new Label("DEA Values: ");
		varUrm = new Label("URM Values: ");
		lbchart = getchart();
		Dimension size = new Dimension(800, 400);
		lbchart.setPreferredSize(size);
		BorderLayout B = new BorderLayout();
		
		
		p.setLayout(B);
		p.add(lbchart, BorderLayout.CENTER);
		
		JPanel south = new JPanel();
		south.setLayout(new BoxLayout(south, BoxLayout.Y_AXIS));
		south.add(distance);
		south.add(varDea);
		south.add(varUrm);
		south.add(varPdm);
		p.add(south, BorderLayout.SOUTH);
		p.add(sb, BorderLayout.EAST);
		
		if(frame.getContentPane().getComponentCount()>=2){
			frame.getContentPane().remove(1);
		}
		frame.getContentPane().add(p, BorderLayout.CENTER);
		frame.pack();
	}

	private static LBChart2D getchart() {

		// Configure object properties
		Object2DProperties object2DProps = new Object2DProperties();
		object2DProps.setObjectTitleText("PDM");

		// Configure chart properties
		Chart2DProperties chart2DProps = new Chart2DProperties();
		chart2DProps.setChartDataLabelsPrecision(-3);
		
		// Configure legend properties
		LegendProperties legendProps = new LegendProperties();
	    String[] legendLabels = {"URM", "DEA", "PDM"};
	    legendProps.setLegendLabelsTexts (legendLabels);

		// Configure graph chart properties
		GraphChart2DProperties graphChart2DProps = new GraphChart2DProperties();
		graphChart2DProps.setLabelsAxisExistence(false);
		graphChart2DProps.setLabelsAxisTitleText("Outputs");
		graphChart2DProps.setNumbersAxisTitleText("Value");

		// Configure graph properties
		GraphProperties graphProps = new GraphProperties();
		//graphProps.setGraphLinesThicknessModel(3);
		//graphProps.setGraphBarsExistence(false);
		//graphProps.setGraphLinesExistence(true);
		graphProps.setGraphAllowComponentAlignment (true);
	    graphProps.setGraphBarsRoundingRatio (0f);
		graphProps.setGraphOutlineComponentsExistence(true);
		//graphProps.setGraphAllowComponentAlignment(true);

		double[] tempData = new double[URMvariables.length];
		
		Dataset dataset = new Dataset(3, URMvariables.length, 1);
		for (int i = 0; i < URMvariables.length; i++) {
			tempData[i] = Pdm.RoundUp(URMvariables[i] / URMvariables[0]);
			dataset.set(0, i, 0, Float.parseFloat(String.valueOf(tempData[i])));
			//Pdm.print(URMvariables[i] + " / " + URMvariables[0] + " = "+ (URMvariables[i] / URMvariables[0]));
			varUrm.setText(varUrm.getText() + "o" + i + ": " + Pdm.RoundUp(tempData[i], 4) + " ");
			
		}
		for (int i = 0; i < DEAvariables.length - Pdm.dea.dmulist.get(0).Inputs.size(); i++) {
			
			tempData[i] = Pdm.RoundUp(DEAvariables[i] / DEAvariables[0]);
			dataset.set(1, i, 0, Float.parseFloat(String.valueOf(tempData[i])));
			varDea.setText(varDea.getText() + "o" + i + ": " + Pdm.RoundUp(tempData[i], 4) + " ");
			//Pdm.print(DEAvariables[i] + " / " + DEAvariables[0] + " = " + (DEAvariables[i] / DEAvariables[0]));
		}
		for (int i = 0; i < DEAvariables.length - Pdm.dea.dmulist.get(0).Inputs.size(); i++) {
			
			tempData[i] = Pdm.RoundUp(DEAvariables[i] / DEAvariables[0]);
			dataset.set(2, i, 0, Float.parseFloat(String.valueOf(tempData[i])));
			varPdm.setText(varPdm.getText() + "o" + i + ": " + Pdm.RoundUp(tempData[i], 4) + " ");
			//Pdm.print(DEAvariables[i] + " / " + DEAvariables[0] + " = " + (DEAvariables[i] / DEAvariables[0]));
		}

		// Configure graph component colors
		MultiColorsProperties multiColorsProps = new MultiColorsProperties();

		// Configure chart
		LBChart2D chart2D = new LBChart2D();
		chart2D.setObject2DProperties(object2DProps);
		chart2D.setChart2DProperties(chart2DProps);
		chart2D.setLegendProperties(legendProps);
		chart2D.setGraphChart2DProperties(graphChart2DProps);
		chart2D.addGraphProperties(graphProps);
		chart2D.addDataset(dataset);
		chart2D.addMultiColorsProperties(multiColorsProps);

		// Optional validation: Prints debug messages if invalid only.
		if (!chart2D.validate(false))
			chart2D.validate(true);

		// <-- End Chart2D configuration -->

		return chart2D;
	}

	@Override
	public void adjustmentValueChanged(AdjustmentEvent e) {
		Pdm.showNextProfile(e.getAdjustmentType());
		lbchart.repaint();
		//Pdm.print("adjustmentValueChanged");
	}

	public static void SetDistanceCount(double calcDifference, double alpha) {
		distance.setText("Alpha: " + alpha + " Flaeche: "+ calcDifference );
	}

	public static void SetPDMLine(double[] calcPdm) {
		Dataset ds = lbchart.getDataset(0);
		//ds.setSize(3, calcPdm.length - 1, 1);
		//Pdm.print("PDM");
		varPdm.setText("PDM Values: ");
		double[] tempdata = new double[calcPdm.length];
		for (int i = 0; i < calcPdm.length - Pdm.dea.dmulist.get(0).Inputs.size(); i++) {
			
	    	tempdata[i] = Pdm.RoundUp(calcPdm[i]/calcPdm[0]);
	    	
	    	Pdm.print("tempdata[" + i + "] " + (tempdata[i]));
			ds.set(2, i, 0, Float.parseFloat(String.valueOf(tempdata[i])));
			varPdm.setText(varPdm.getText() + "o" + i + ": " + Pdm.RoundUp(tempdata[i], 4) + " ");
		}
	}

	private double IntToAlpha(int sbVal) {
		return (sbVal - 1) * 0.5d;
	}
	@Override
	public void actionPerformed(ActionEvent arg0) {
		if(arg0.getActionCommand().equals("NEWDMU")){
			if(list.getSelectedIndex() >= 0){
				Pdm.print("New DMU selected: " + list.getSelectedIndex());
				SelectDMU(list.getSelectedIndex());
			}
			else
			{
				Pdm.print("No item selected");
			}
		}
		else if (arg0.getActionCommand().equals("FILE")){
			selectFile();
		}
	}
}
